#ifndef _SIP_CLIENT_H_
#define _SIP_CLIENT_H_

#include <osip2/osip_mt.h>
#include <eXosip2/eXosip.h>

struct ctx_sdp_track
{
    char mediaType[11]{0};         // video
    char peerStreamType[40] = {0}; // 96 98 97
    char peerIp[40] = {0};         // 接收国标推流Player的IP地址
    int peerRtpPort = 0;           // 15060
    char peerRtpTransport[20]{0};  // 对端通过sdp发送过来的需要的rtp传输方式：TCP/RTP/AVP or RTP/AVP
};

struct ctx_sip_config
{
    // local part
    char ua[128] = {0};
    char device_name[128] = {0};
    char channle_name[32] = {0};
    char password[20] = {0};
    int sip_register_timeout_second;

    string local_ip;
    int local_sip_port;
    char local_sip_user_id[32] = {0}; //  一般用户名和认证id是一个东西
    int local_rtp_port = 10011;       // 这个是本地的推流端口, 可以自己定义

    // server part
    string server_ip;
    int server_sip_port; //
    char server_sip_id[32] = {0};
    char server_domain[32] = {0};
    int server_rtp_port; // 这个是本地的视频流需要发送到的端口
    unsigned int ssrc;   // 这个是视频流的校验码
};

class cls_sip_client
{
private:
    /* data */
public:
    cls_sip_client(cls_spkcam *p_app);
    ~cls_sip_client();

    cls_spkcam *app;
    device_info *cfg_src;
    device_info *cfg_cur;

    ctx_sip_config sip_config;

    cls_rtp_send_ps *sendps;

    bool sip_client_running;

    std::unique_ptr<std::thread> main_loop_thread;

    void sip_client_main_loop();
    void sip_client_loop_start();
    void sip_client_loop_stop();

private:
    struct eXosip_t *mSipCtx;
    bool mRegistered; // 判断是否注册成功
    int mRegisterId;

    void init_sip_conf();

    int init_sip_client();
    int sip_event_handle(eXosip_event_t *evtp);
    int response_message_answer(eXosip_event_t *evtp, int code);
    int response_message(eXosip_event_t *evtp);
    int response_invite(eXosip_event_t *evtp);
    int response_ack(eXosip_event_t *evtp);
    int response_bye(eXosip_event_t *evtp);
    int request_register();

    int request_message_keepalive();
    int request_message_catalog(int sn);
    int response_message_deviceinfo(int sn);

    int parse_xml(const char *data, const char *s_mark, bool with_s_make, const char *e_mark, bool with_e_make, char *dest);
    void dump_request(eXosip_event_t *evt);
    void dump_response(eXosip_event_t *evt);
};

#endif //  _SIP_CLIENT_H_